888G - Xor-MST - CodeForces Solution


bitmasks constructive algorithms data structures *2300

Please click on ads to support us..

C++ Code:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
 
class UnionFind {
private:
    vector<int> p, setSize;
    int numSets;
public:
    vector<vector<int>> adj;
 
    UnionFind(int N) {
        p.assign(N, 0);
        for (int i = 0; i < N; i++) {
            p[i] = i;
        }
        setSize.assign(N, 1);
        numSets = N;
        adj.resize(N);
        for (int i = 0; i < N; i++) {
            adj[i].push_back(i);
        }
    }
 
    int findSet(int i) {
        return (p[i] == i) ? i : (p[i] = findSet(p[i]));
    }
 
    bool isSameSet(int i, int j) {
        return findSet(i) == findSet(j);
    }
 
    int numDisjointSets() {
        return numSets;
    }
 
    int sizeOfSet(int i) {
        return setSize[findSet(i)];
    }
 
    void unionSet(int i, int j) {
        if (isSameSet(i, j)) return;
        int x = findSet(i), y = findSet(j);
        if (setSize[x] > setSize[y]) swap(x, y);
        p[x] = y;
        setSize[y] += setSize[x];
        numSets--;
        for (auto &x: adj[x]) {
            adj[y].push_back(x);
        }
        adj[x].clear();
    }
};

const int N = 2e5 + 9;
 
int t[N * 30][2], sz;
int el[N * 30], tot[N * 30];
void add(int x, int id) {
    int cur = 0;
    tot[cur]++;
    for (int i=30; i>=0; i--) {
        bool b = x&(1<<i);
        if (t[cur][b] == 0) t[cur][b] = ++sz;
        cur = t[cur][b];
        tot[cur]++;
    }
    el[cur] = id;
}
 
void del(int x, int id) {
    int cur = 0;
    tot[cur]--;
    for (int i=30; i>=0; i--) {
        bool b = x&(1<<i);
        cur = t[cur][b];
        tot[cur]--;
    }
    assert(el[cur] == id);
    el[cur] = 0;
}
 
int minxor(int x) {
    int cur = 0;
    for (int i=30; i>=0; i--) {
        bool b = x&(1<<i);
        if (t[cur][b] && tot[t[cur][b]] > 0)  cur = t[cur][b];
        else cur = t[cur][!b];
    }
    // assert(el[cur]);
    return el[cur];
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int n;
    cin >> n;
 
    vector<int> a(n);
    for (auto &x: a) cin >> x;
 
    sort(a.begin(), a.end());
    a.resize(unique(a.begin(), a.end()) - a.begin());
    n = a.size();
 
    UnionFind dsu(n);
    ll ans = 0;
 
    for (int i = 0; i < n; i++) {
        add(a[i], i);
    }
 
    int cntIterations = 0;
    while (dsu.numDisjointSets() > 1) {
        cntIterations++;
        assert(cntIterations <= 25);
        vector<pair<int, int>> toMerge;
        
        for (int i = 0; i < n; i++) {
            auto &comp = dsu.adj[i];
            if (dsu.findSet(i) != i || (int) comp.size() == 0) continue;
            for (auto &x: comp) {
                del(a[x], x);
            }
            
            int from = -1, to = -1;
            for (auto &i: comp) {
                int cur = minxor(a[i]);
                if (from == -1 || ((a[i] ^ a[cur]) < (a[from] ^ a[to]))) {
                    from = i;
                    to = cur;
                }
            }
 
            assert(from != -1 && to != -1);
            toMerge.push_back({from, to});
 
            for (auto &x: comp) {
                add(a[x], x);
            }
        }
 
        assert(!toMerge.empty());
        for (auto &[from, to]: toMerge) {
            if (!dsu.isSameSet(from, to)) {
                dsu.unionSet(from, to);
                ans += a[from] ^ a[to];
            }
        }
    }
 
    cout << ans;
}


Comments

Submit
0 Comments
More Questions

1627B - Not Sitting
1663C - Pōja Verdon
1497A - Meximization
1633B - Minority
688B - Lovely Palindromes
66B - Petya and Countryside
1557B - Moamen and k-subarrays
540A - Combination Lock
1553C - Penalty
1474E - What Is It
1335B - Construct the String
1004B - Sonya and Exhibition
1397A - Juggling Letters
985C - Liebig's Barrels
115A - Party
746B - Decoding
1424G - Years
1663A - Who Tested
1073B - Vasya and Books
195B - After Training
455A - Boredom
1099A - Snowball
1651D - Nearest Excluded Points
599A - Patrick and Shopping
237A - Free Cash
1615B - And It's Non-Zero
1619E - MEX and Increments
34B - Sale
1436A - Reorder
1363C - Game On Leaves